import serial, threading, time, random
from socket import *
import traceback
import win32security
import win32api
import sys, os
from ntsecuritycon import *

myHost = ''
myPort = 2001
COMPORT= 2
BAUD = 9600
TIMEOUT = 2

versuch = 0
while (versuch < 10):
    try:
        ser = serial.Serial(COMPORT, BAUD)
        comporterror=False
        print ser.portstr
        break
    except:
        wartezeit=random.random()
        print "COM error? erneuter versuch nach " + str(wartezeit) + " Sekunden"
        time.sleep(wartezeit)
        comporterror=True
        versuch +=1
if versuch == 10:
    print "konnte COM" + str(COMPORT) + " nicht oeffnen!" 
    comporterror=True
    

s = socket(AF_INET, SOCK_STREAM)    # create a TCP socket
s.bind((myHost, myPort))            # bind it to the server port
s.listen(5)

#===============================================================================
# safty
#===============================================================================
def safty(): # Timeout, keine Nachricht erhalten, wir schalten in den "Safty" modus.
    versuch=0
    while (versuch < 100): # hundert versuche
        try:
            ser.write(chr(255) + chr(254)+chr(1)+chr(127)+chr(254)+chr(2)+chr(127) + chr(0) )
            #ser.write(chr(255))
            #ser.write(chr(254)+chr(1)+chr(127))
            #ser.write(chr(255))
            print "safty"
            print ser.read(ser.inWaiting()),
            break
        except:
            wartezeit=random.random()
            print "COM Port belegt? erneuter versuch nach" + str(wartezeit) + " Sekunden"
            time.sleep(wartezeit)
            versuch +=1
            continue
    #Panik!! hier sollten wir nie hinkommen!!
    if versuch == 100:
        comporterror=True

#===============================================================================
# Server Reboot
#===============================================================================

def RebootServer(message='Server Rebooting', timeout=10, bForce=1, bReboot=1):
    AdjustPrivilege(SE_SHUTDOWN_NAME)
    try:
        win32api.InitiateSystemShutdown("raupe", message, timeout, bForce, bReboot)
    finally:
        # Remove the privilege we just added.
        AdjustPrivilege(SE_SHUTDOWN_NAME, 0)


def AbortReboot():
    AdjustPrivilege(SE_SHUTDOWN_NAME)
    try:
        win32api.AbortSystemShutdown(None)
    finally:
        # Remove the privilege we just added.
        AdjustPrivilege(SE_SHUTDOWN_NAME, 0)


def AdjustPrivilege(priv, enable=1):
    # Get the process token.
    flags = TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
    htoken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), flags)
    # Get the ID for the system shutdown privilege.
    id = win32security.LookupPrivilegeValue(None, priv)
    # Obtain the privilege for this process.
    # Create a list of the privileges to be added.
    if enable:
        newPrivileges = [(id, SE_PRIVILEGE_ENABLED)]
    else:
        newPrivileges = [(id, 0)]
    # and make the adjustment.
    win32security.AdjustTokenPrivileges(htoken, 0, newPrivileges)

#===============================================================================
# Funktion Change Resolution
#===============================================================================
def ChangeResolution(resolution):   
    #os.system("taskkill /im WebCam.exe /f")
    #time.sleep(1)
    os.system(r"start /B AWCStarter.cmd "+ resolution + ".AWSes")
    time.sleep(1)

#===============================================================================
# Thread Blinken, wird ausgefuert wenn keine Client verbunden ist
#===============================================================================

class blinken(threading.Thread):
    def __init__(self):
        self.stopped = False
        threading.Thread.__init__(self)
        
    def run(self):
        licht = True
        while 1:
            time.sleep(1)
            if self.stopped:
                continue
            ser.write(chr(255) + chr(254)+chr(1)+chr(127)+chr(254)+chr(2)+chr(127) + chr(0) )
            licht = not licht
            if licht:
                try:
                    
                    ser.write(chr(255)+chr(252)+chr(1)+chr(1)+chr(0))
                    #ser.write(chr(255))

                except:
                    continue
            else:
                try:
                    
                    ser.write(chr(255)+chr(252)+chr(1)+chr(254)+chr(0))
                    #ser.write(chr(255))

                except:
                    continue
            #print ser.read(ser.inWaiting()),
            if ser.inWaiting():
                print "\r"
            for char in ser.read( ser.inWaiting()):
                print ord(char)/20.0,
        exit()
        
t=threading.Timer(1, safty) # Nach 1 Sekunde ohne Signal, wird Angehalten
blinklicht = blinken()

if not comporterror:      
    t.start()
    blinklicht.start()
                
while 1:
    
    print "warte auf Client"
    blinklicht.stopped = False
    
    try:
        connection, address = s.accept() # connection is a new socket
        
    except:
        print "Fehler bei der Verbindungsherstellung..."
        continue
    
    blinklicht.stopped = True
    
    try:
        ser.write(chr(255) + chr(252)+chr(1)+chr(1) + chr(0)) #Licht default aus
    except:
        print "kann nicht auf die Serielle schnittstelle zugreifen"
        comporterror=True
    
    while 1:
        t=threading.Timer(1, safty)
        t.start()
        try:
            connection.settimeout(TIMEOUT)
            data = connection.recv(1024) # receive up to 1K bytes
        except:
            print "Timeout"
            data = False
        t.cancel()
        try:
            if comporterror:
                connection.send("COMPORTERROR: COM" + str(COMPORT))
            else:
                connection.send("OK")
        except:
            print "Verbindung unterbrochen"
            break
        if data:
            if "RES" in data:
                ChangeResolution(data.split(";")[1])
                safty()
                continue
            if "COMPORT" in data:
                continue
            if "REBOOT" in data:
                RebootServer("ausdiemaus")
                safty()
                break
            while 1:
                try:
                    ser.write(chr(255)+data+chr(0))
                    #ser.write(chr(255))
                    #print(data)
                    #data=chr(255) + data + chr(0)
                    #for ch in data:
                    #    ser.write(ch)
                        #while ser.read(1) != ch:
                        #    pass
                    #    time.sleep(0.005)
                    #    print ord(ch),
                    #print " "
                    break
                except:
                    time.sleep(0.1)
                    continue

            #for i in range(ser.inWaiting()):
            if ser.inWaiting() >=2:
                serrec=ser.read(ser.inWaiting())
                if ord(serrec[0])==255:
                    print "bat1: ", ord(serrec[1])/20.0
                
            #print ser.read(ser.inWaiting()),
            #+for char in ser.read( ser.inWaiting()):
                
             #   print ord(char),
            #print " "
            #print ord(ser.read(ser.inWaiting())),
            #i=0;
            #for ch in data:           
            #    print "\r", i, ord(ch), 
            #    i+=1         
        else:
            print "break"
            safty()
            break
    connection.close()              # close socket
